package com.codefish.codefish_blog.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 * 客户代码通过key "userInfo"获取payload中装载的数据
 *
 * @author codefish
 * @version 1.0
 * @date 2022/04/10 下午 08:57
 */
public class JwtUtil {
    /**
     * 密钥
     */
    private static final String SECRET_KEY = "secret";
    /**
     * 加密算法
     */
    private static final Algorithm ALGORITHM = Algorithm.HMAC256(SECRET_KEY);
    /**
     * 签证署名
     */
    private static final String ISSUER = "com.codefish";
    /**
     * token过期时间,默认2h,单位s
     */
    public static final Long EXPIRE_TIME = 2 * 60 * 60L;
    //public static final Long EXPIRE_TIME=30L;

    /**
     * 签发JWT token
     *
     * @param payload JWT负载数据
     * @return jwt token字符串
     */
    public static String createJwtToken(Map<String, Object> payload) {
        //实例化jwt builder
        JWTCreator.Builder builder = JWT.create();
        //jwt 头部信息
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");
        builder.withHeader(header);
        //jwt payload信息
        builder.withClaim("userInfo", payload);
        //获取当前时间
        Date nowDate = new Date();
        builder.withIssuedAt(nowDate);
        //设置过期时间为120min
        Date expireDate = new Date(nowDate.getTime() + EXPIRE_TIME * 1000);
        builder.withExpiresAt(expireDate);
        //token签发署名
        builder.withIssuer(ISSUER);
        //加密token并返回字符串
        return builder.sign(ALGORITHM);
    }

    /**
     * 返回token解析结果，客户代码需要知道DecodedJWT类
     *
     * @param token 请求携带的token字符串
     * @return DecodedJWT对象, 对token的解析结果
     * @throws JWTDecodeException 异常
     */
    public static DecodedJWT verify(String token) throws Exception {
        //验证token是否有效
        if (StringUtils.isEmpty(token)) {
            throw new JWTDecodeException("无效的token!");
        }
        //返回解析结果
        return JWT.require(ALGORITHM).build().verify(token);
    }

}
